今天來搭配Docker來跑看看!
還沒使用OTel collector之前, 大概大家都這樣做
我用mingrammer/flog
這是apache log產生器kscarlett/nginx-log-generator
這個則是nginx log產生器
程式結構
/
docker-compose.yaml
conf/
fluent-bit.conf
parsers.conf
version: '3'
services:
fluentbit:
image: fluent/fluent-bit
volumes:
- ./conf:/fluent-bit/etc
ports:
- "24224:24224"
- "24224:24224/udp"
hostname: fluentd
flog:
image: mingrammer/flog
command: '-l'
depends_on:
- fluentbit
command: "-s 2 -n 5"
logging:
driver: fluentd
options:
tag: apache
nginx:
image: kscarlett/nginx-log-generator
depends_on:
- fluentbit
environment:
- RATE=1
- DELETE_PERCENT=5
logging:
driver: fluentd
options:
tag: nginx
loki:
image: grafana/loki:latest
ports:
- "3100:3100"
command: -config.file=/etc/loki/local-config.yaml
grafana:
image: grafana/grafana:latest
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_USER=admin
- GF_SECURITY_ADMIN_PASSWORD=admin
- GF_USERS_ALLOW_SIGN_UP=false
fluent-bit.conf
[SERVICE]
flush 1
Daemon off
log_level debug
http_server on
http_listen 0.0.0.0
storage.metrics on
Config_Watch On
parsers_file parsers.conf
[INPUT]
Name forward
Listen 0.0.0.0
port 24224
[FILTER]
Name parser
Match apache
Key_Name log
Parser apache
[FILTER]
Name record_modifier
Match apache
Record log_type apache
[FILTER]
Name parser
Match nginx
Key_Name log
Parser nginx
[FILTER]
Name record_modifier
Match nginx
Record log_type nginx
[OUTPUT]
name loki
match *
host loki
port 3100
labels job=demo
[OUTPUT]
Name stdout
Format json
parsers.conf
[PARSER]
Name apache
Format regex
Regex ^(?<host>[^ ]*) [^ ]* (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^\"]*?)(?: +\S*)?)?" (?<code>[^ ]*) (?<size>[^ ]*)(?: "(?<referer>[^\"]*)" "(?<agent>[^\"]*)")?$
Time_Key time
Time_Format %d/%b/%Y:%H:%M:%S %z
[PARSER]
Name nginx
Format regex
Regex ^(?<remote>[^ ]*) (?<host>[^ ]*) (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^\"]*?)(?: +\S*)?)?" (?<code>[^ ]*) (?<size>[^ ]*)(?: "(?<referer>[^\"]*)" "(?<agent>[^\"]*)")
Time_Key time
Time_Format %d/%b/%Y:%H:%M:%S %z
然後執行起來
docker-compose up -d
瀏覽器打開http://localhost:3000/login
預設帳號密碼admin
/admin
左邊選擇DataSources, 然後新增, 選擇Loki
晚點會把它寫成provisioning!!
URL填入http://loki:3100,
按下Save&Test
接著到Explore, DataSource選擇Loki
就能看到剛剛在FluentBit新增的job demo了
想練習前三天介紹的LogQL, 這裡就有很多資料能把玩了:)
這樣子的架構是因為, FluetBit有提供OpenTelemetry的Output組件.
也有提供Loki的Output組件
真心強大的FluentBit:)
但我們也能這樣玩
直接把程式的log, 輸出到OTel collector上, 再匯出到Loki.
OTel Collector有提供Fluent Forward Receiver
(但這條路目前崎嶇難行就是QQ)
程式結構
/
docker-compose.yaml
otel/
otel-collector-config.yml
docker-compose.yaml
version: '3'
services:
flog:
image: mingrammer/flog
command: '-l'
depends_on:
- otel-collector
command: ["--delay=2s", "--number=1", "--format=json", "--loop"]
logging:
driver: fluentd
options:
fluentd-address: localhost:24224
# Allow time for otel-collector to spin up, then forward fluentd logs to the fluentforwarder receiver.
fluentd-async-connect: "true"
# Use nanosecond precision
fluentd-sub-second-precision: "true"
tag: apache
nginx:
image: kscarlett/nginx-log-generator
depends_on:
- otel-collector
environment:
- RATE=1
- DELETE_PERCENT=5
logging:
driver: fluentd
options:
fluentd-address: localhost:24224
# Allow time for otel-collector to spin up, then forward fluentd logs to the fluentforwarder receiver.
fluentd-async-connect: "true"
# Use nanosecond precision
fluentd-sub-second-precision: "true"
tag: nginx
loki:
image: grafana/loki:latest
ports:
- "3100:3100"
command: -config.file=/etc/loki/local-config.yaml
grafana:
image: grafana/grafana:latest
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_USER=admin
- GF_SECURITY_ADMIN_PASSWORD=admin
- GF_USERS_ALLOW_SIGN_UP=false
otel-collector:
image: otel/opentelemetry-collector-contrib
command: ["--config=/etc/otel-collector-config.yml"]
volumes:
- ./otel/otel-collector-config.yml:/etc/otel-collector-config.yml
ports:
- "1888:1888" # pprof extension
- "13133:13133" # health_check extension
- "55679:55679" # zpages extension
- "24224:24224" # fluentforwarder
- "24224:24224/udp" # fluentforwarder
depends_on:
- loki
otel-collector-config.yml
receivers:
fluentforward:
endpoint: 0.0.0.0:24224
processors:
batch:
send_batch_size: 50
timeout: 5s
memory_limiter:
check_interval: 2s
limit_mib: 1800
spike_limit_mib: 500
extensions:
health_check:
pprof:
endpoint: :1888
zpages:
endpoint: :55679
memory_ballast:
# Memory Ballast size should be max 1/3 to 1/2 of memory.
size_mib: 64
exporters:
logging:
loglevel: debug
loki:
endpoint: "http://loki:3100/loki/api/v1/push"
# Will encode the whole OTEL message in json
# This format happen after extracting labels
format: json
labels:
attributes:
container_name: ""
source: ""
resource:
host.name: "hostname"
service:
extensions: [pprof, zpages, health_check, fluentbit]
pipelines:
logs:
receivers: [fluentforward]
processors: [ memory_limiter, batch ]
exporters: [loki, logging]
然後執行起來
docker-compose up -d
瀏覽器打開http://localhost:3000/login
預設帳號密碼admin
/admin
左邊選擇DataSources, 然後新增, 選擇Loki
晚點會把它寫成provisioning!!
URL填入http://loki:3100,
按下Save&Test
接著到Explore, DataSource選擇Loki
就能看到剛剛在FluentBit新增的label了
查詢了一下能發現到body的問題
嘗試用前天提到的json parsing expression
問題依舊
能善用也是前幾天提到的line_format, 只提取出body形成新的log後再json parse
{container_name="/demo_log_flog_1"} | json | line_format "{{.body}}" | json
可是FluentBit不是也能寫一堆parser嘛? 參考Log Agent - Fluent Bit Parser元件
怎麼還要在這用LogQL轉?
因為這裡
Deprecated FluentBit Subprocess Extension
FluentBit的OTel collector extension目前被棄用了QQ
所以之前的那個架構還是有存在的必要, 先到FluentBit弄好後再往Collector拋. 但就是更複雜了.
DataSource確定能連線後, 我們應該就要建立成Provisioning, 方便進入版控, 拉下來佈署時就能直接配置好了(CAC).
程式結構
/
docker-compose.yaml
otel/
otel-collector-config.yml
provisioning/
datasources/
loki.yaml
loki.yaml
# config file version
apiVersion: 1
datasources:
- name: Loki
type: loki
url: http://loki:3100
docker-compose.yaml
grafana:
image: grafana/grafana:latest
ports:
- "3000:3000"
volumes:
- ./provisioning/datasources/:/etc/grafana/provisioning/datasources/
environment:
- GF_SECURITY_ADMIN_USER=admin
- GF_SECURITY_ADMIN_PASSWORD=admin
- GF_USERS_ALLOW_SIGN_UP=false
一登入成功後, Loki就在data sources內了:)
Provisioning能回憶我前幾天的文章
淺談Provisioning Grafana
hmm...FluentBit真心好用(喂)
OTelCellector真的支持很都多種協議跟接口, 不過在選用之前還是得要注意是否有狀態是Deprecated的.
該狀態也能回顧這次小弟的文章淺談OpenTelemetry
但真的不失為是一個高度整合性的解決方案.
OpenTelemetry Collector Contrib
您好,想請問在opentelemetry-contrib下的traceid、spanid可以直接在log內生成hashcode嗎?還是需要藉由trace工具才能達成呢?謝謝。
你好, 如果是要透過traceid+spanid兩個組成hashcode
可以的, 能參考小弟這篇https://ithelp.ithome.com.tw/articles/10288979 的baggage or span tag
把hashcode塞進去即可
若是要拿traceid or span id能看看span context
https://opentelemetry.io/docs/reference/specification/trace/api/#retrieving-the-traceid-and-spanid